<template>
    <admin-module id="role_management" v-loading="loading">
        <template slot="header">
            <el-form size="small" inline label-position="left" label-width="70px" @submit.native.prevent>
                <el-form-item label="角色名称">
                    <el-input placeholder="根据角色名称搜索" clearable v-model="whereForm.keyword"> </el-input>
                </el-form-item>
                <el-form-item label="创建时间">
                    <el-date-picker type="daterange" align="right" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" v-model="whereForm.dateRange"> </el-date-picker>
                </el-form-item>
                <el-form-item label-width="0px">
                    <el-button type="primary" size="small" icon="el-icon-search" native-type="submit" @click="handleSearch"> 搜索 </el-button>
                </el-form-item>
            </el-form>
        </template>
        <template slot="action">
            <el-button type="primary" size="small" icon="el-icon-plus" @click="handleCreate"> 添加 </el-button>
            <el-button type="danger" size="small" icon="el-icon-delete" :disabled="!isSelectedRows" @click="handleDeleteMulti"> 删除 </el-button>
            <el-button type="default" size="small" icon="el-icon-refresh-right" @click="handleReload" :loading="loading" :disabled="loading">
                {{ loading ? "刷新中" : "刷新" }}
            </el-button>
        </template>
        <template slot="paginate">
            <el-pagination @size-change="getData" @current-change="getData" :current-page.sync="whereForm.page" :page-sizes="[10, 20, 30, 40]" :page-size.sync="whereForm.limit" :total="whereForm.total" layout="total, sizes, prev, pager, next, jumper"> </el-pagination>
        </template>
        <template>
            <el-table :data="tableData" stripe="" empty-text="暂未添加任何角色" @selection-change="handleSelectedRows" :max-height="maxHeight">
                <el-table-column type="selection" width="50" align="center" fixed="left"> </el-table-column>
                <el-table-column label="角色名称" width="150" prop="name" sortable="" :formatter="notEmpty"> </el-table-column>
                <el-table-column label="备注信息" min-width="200" prop="remark" sortable="" :formatter="notEmpty"> </el-table-column>
                <el-table-column label="排序号" width="100" align="center" prop="sort" sortable="" :formatter="notEmpty"> </el-table-column>
                <el-table-column label="是否启用" width="100" align="center" prop="status" sortable="" :formatter="notEmpty">
                    <template slot-scope="scope">
                        <el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" @change="(data) => handleChangeStatus(data, scope.row)"> </el-switch>
                    </template>
                </el-table-column>
                <el-table-column label="创建时间" width="200" prop="create_time" align="center" sortable="" :formatter="notEmpty"> </el-table-column>
                <el-table-column label="更新时间" width="200" prop="update_time" align="center" sortable="" :formatter="notEmpty"> </el-table-column>
                <el-table-column label="操作" width="200" fixed="right" align="center" :formatter="notEmpty">
                    <template slot-scope="scope">
                        <el-button-group>
                            <el-button size="mini" round type="primary" @click="handleEdit(scope.row)"> 修改 </el-button>
                            <el-button size="mini" round type="danger" @click="handleDelete(scope.row)"> 删除 </el-button>
                        </el-button-group>
                    </template>
                </el-table-column>
            </el-table>
            <el-dialog :title="dialogFormTitle" :visible.sync="showDialogForm" width="720px" :close-on-click-modal="false">
                <el-form label-position="left" label-width="80px" @submit.native.prevent :rules="rules" ref="form" :model="form">
                    <el-row :gutter="20">
                        <el-col :span="12">
                            <el-form-item label="角色名称" prop="name">
                                <el-input type="text" placeholder="请输入角色名称" clearable="" v-model="form.name"> </el-input>
                            </el-form-item>
                            <el-form-item label="角色介绍">
                                <el-input type="textarea" placeholder="请输入角色介绍" clearable="" :rows="5" v-model="form.remark"> </el-input>
                            </el-form-item>
                            <el-form-item label="排序号">
                                <el-tooltip content="数字越大越靠前显示" placement="top-start">
                                    <el-input-number v-model="form.sort" placeholder="排序号"> </el-input-number>
                                </el-tooltip>
                            </el-form-item>
                        </el-col>
                        <el-col :span="12">
                            <el-form-item label="配置权限">
                                <div class="selected-perm">
                                    <el-tree empty-text="暂无数据" :data="permTree" show-checkbox node-key="id" :props="treeProps" ref="tree" default-expand-all> </el-tree>
                                </div>
                            </el-form-item>
                        </el-col>
                    </el-row>
                    <el-form-item>
                        <el-button type="primary" native-type="submit" @click="handleSave">保存</el-button>
                    </el-form-item>
                </el-form>
            </el-dialog>
        </template>
    </admin-module>
</template>

<script>
import { cloneDeep } from "lodash";

export default {
    data() {
        return {
            // 表格最大高度
            maxHeight: document.documentElement.clientHeight - 300,
            // 是否在加载中
            loading: false,
            // 权限树
            permTree: [],
            treeProps: {
                children: "children",
                label: "name",
            },
            // 表格数据
            tableData: [],
            // 当前操作行数据
            form: {},
            // 表单校验规则
            rules: {
                name: [{ required: true, message: "角色名不能为空", trigger: "blur" }],
            },
            // 是否显示模态框
            showDialogForm: false,
            showDialogPerm: false,
            // 选中行数据
            selectedRows: [],
            // 过滤条件
            whereForm: {
                page: 1,
                limit: 20,
                keyword: "",
                dateRange: [],
                total: 0,
            },
        };
    },
    created() {
        this.getData();
        this.getPermTree();
    },
    computed: {
        // 行数据是否有id,用于区分是新建还是修改
        hasRowId() {
            const { form } = this;
            return form.id ? true : false;
        },
        // 模态框标题
        dialogFormTitle() {
            const { hasRowId } = this;

            return hasRowId ? "修改角色" : "添加角色";
        },
        // 选择的行数据
        isSelectedRows() {
            const { selectedRows } = this;

            return selectedRows.length > 0;
        },
        // 选择的行数据id
        selectedRowsIds() {
            const { selectedRows } = this;

            const ids = [];

            for (const row of selectedRows) {
                ids.push(row.id);
            }

            return ids;
        },
        // 关键词
        keyword() {
            return this.whereForm.keyword;
        },
    },
    watch: {
        keyword(keyword) {
            if (!keyword) this.getData();
        },
    },
    methods: {
        /**
         * 改变启用状态
         */
        handleChangeStatus(value, row) {
            const { id, status } = row;

            this.$post("/role_management/update", { id, status }).then((res) => {
                const { msg, code } = res;
                if (code === 200) {
                    this.getData();
                } else {
                    row.status = value == 1 ? 0 : 1;
                }
            });
        },
        /**
         * 搜索
         */
        handleSearch() {
            this.getData();
        },
        /**
         * 当选中行
         * @param {array} rows 选中行数据
         */
        handleSelectedRows(rows) {
            this.selectedRows = cloneDeep(rows);
        },
        /**
         * 表单数据初始化
         */
        resetForm() {
            this.form = {
                name: "",
                remark: "",
                permssions: "",
                sort: 0,
            };
        },
        /**
         * 移除行数据
         * @param {array} ids 行数据id,支持多个id
         */
        removeRow(ids = []) {
            if (Object.prototype.toString.call(ids) === "[object Array]") ids = ids.join(",");

            return this.$post("/role_management/remove", { id: ids });
        },
        /**
         * 检查数据是否为空,如果空就返回 value
         */
        notEmpty(row, col, value, index) {
            return value || "-";
        },
        /**
         * 渲染权限树
         * @param {array} ids 权限id 支持多个
         */
        renderPermTree(ids = []) {
            this.$refs.tree.setCheckedKeys([]);
            this.$nextTick(() => {
                for (const id of ids) {
                    const node = this.$refs.tree.getNode(id);
                    if (node.isLeaf) this.$refs.tree.setChecked(node, true);
                }
            });
        },
        /**
         * 提交表单
         */
        handleSave() {
            this.$refs.form.validate((valid) => {
                if (valid) {
                    const perms = this.$refs.tree.getCheckedNodes(false, true);
                    const ids = [];
                    for (const perm of perms) {
                        ids.push(perm.id);
                    }
                    const form = cloneDeep(this.form);
                    form.perm = ids.join(",");
                    delete form.perm_list;

                    if (form.id) {
                        this.$post("/role_management/update", form).then((res) => {
                            const { msg, code } = res;

                            if (code === 200) {
                                this.showDialogForm = false;
                                this.getData();
                            }
                        });
                    } else {
                        this.$post("/role_management/create", form).then((res) => {
                            const { msg, code } = res;

                            if (code === 200) {
                                this.showDialogForm = false;
                                this.getData();
                            }
                        });
                    }
                } else {
                    return false;
                }
            });
        },
        /**
         * 当修改的时候
         */
        handleEdit(data) {
            this.resetForm();
            this.form = cloneDeep(data);
            this.showDialogForm = true;
            this.$nextTick(() => {
                this.renderPermTree(data.perm.split(","));
            });
        },
        /**
         * 当删除的时候
         */
        handleDelete(data) {
            this.$confirm("是否要删除该数据? ", "删除确认", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then(() => {
                    this.removeRow(data.id).then((res) => {
                        if (res.code == 200) {
                            this.$message({
                                type: "success",
                                message: "删除成功!",
                            });
                            this.getData();
                        }
                    });
                })
                .catch(() => {});
        },
        /**
         * 批量删除
         */
        handleDeleteMulti() {
            this.$confirm("是否要删除选中的数据? ", "删除确认", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then(() => {
                    const { selectedRowsIds } = this;

                    this.removeRow(selectedRowsIds).then((res) => {
                        if (res.code == 200) {
                            this.$message({
                                type: "success",
                                message: "删除成功!",
                            });
                            this.getData();
                        }
                    });
                })
                .catch(() => {});
        },
        /**
         * 当刷新的时候
         */
        handleReload() {
            this.getData().then(() => {
                this.$message.success("刷新成功");
            });
        },
        /**
         * 当创建的时候
         */
        handleCreate() {
            this.resetForm();
            this.showDialogForm = true;
            this.$nextTick(() => {
                this.renderPermTree();
            });
        },
        /**
         * 获取权限树
         */
        getPermTree() {
            this.$get("/role_management/permTree").then((res) => {
                const { code, data } = res;
                if (code == 200) {
                    this.permTree = cloneDeep(data);
                }
            });
        },
        /**
         * 获取数据
         */
        getData() {
            return new Promise((resolve, reject) => {
                const { keyword, dateRange, page, limit } = this.whereForm;

                const form = { page, limit };
                if (keyword) form.keyword = keyword;

                if (dateRange && dateRange.length == 2) {
                    form.startTime = dateRange[0];
                    form.endTime = dateRange[1];
                }

                this.loading = true;
                this.$get("/role_management/list", { params: form })
                    .then((res) => {
                        this.loading = false;
                        const { code, msg, data } = res;
                        if (code === 200) {
                            const { total, data: rows, current_page: page } = data;
                            this.whereForm.page = page;
                            this.whereForm.total = total;
                            this.tableData = cloneDeep(rows);
                            resolve();
                        } else {
                            reject(new Error(msg));
                        }
                    })
                    .catch((err) => {
                        this.loading = false;
                        reject(err);
                    });
            });
        },
    },
};
</script>

<style lang="scss" scoped>
#role_management {
    .selected-perm {
        padding: 4px 0px;
        max-height: 200px;
        overflow-y: auto;
        background-color: #f6f6f6;
        border-radius: 3px;
        box-shadow: 0px 1px 5px rgba($color: #000000, $alpha: 0.1) inset;

        .el-tree {
            background-color: transparent;

            ::v-deep .el-tree-node__content:hover {
                background-color: transparent;
            }
        }
    }
}
</style>
